#include "sensor_electrode.h"
#include "sensor_celectrode.h"

//Constant definition

#define BUFFER_SIZE                 5

#define VOLTAGE_MIN             (  10 * PERCISION / 100 )
#define VOLTAGE_MAX             ( 320 * PERCISION / 100 )
#define VOLTAGE_SHORTED         ( 120 * PERCISION / 100 )
#define VOLTAGE_ACC_MAX         (  20 * PERCISION / 100 )
#define THRESHOLD_TIME          (  20 * SAMPLES_PER_HOUR / MINUTES_PER_HOUR )
#define SHORTED_THRESHOLD_TIME  (  12 * SAMPLES_PER_HOUR )

// Private variable definition

static fixed32 m_f32_voltage = 0;
static cycle_buffer m_t_buffer = {0};
static fixed32 m_f32_bufferData[BUFFER_SIZE] = {0};

static fixed32 m_f32_voltageAcc = 0;

static uint32  m_u32_railCounter = 0;
static uint32  m_u32_shortedCounter = 0;
static uint32  m_u32_deficitCounter = 0;

#define VC_DAY_BUFFER_SIZE (SAMPLES_PER_HOUR * 12)
static fixed32 m_f32_vcDayBufferData[VC_DAY_BUFFER_SIZE] = {0};
static cycle_buffer m_t_vcDayBuffer = {0};

// Function definition

void CE_Initialize(void)
{
    CE_Reset();
}

void CE_Reset(void)
{
    m_f32_voltage = 0;
    m_u32_railCounter = 0;
    m_u32_shortedCounter = 0;
    m_u32_deficitCounter = 0;
    m_f32_voltageAcc = VOLTAGE_ACC_MAX;
    Buffer_Init( &m_t_buffer, &m_f32_bufferData[0], BUFFER_SIZE );
    Buffer_Init(&m_t_vcDayBuffer, m_f32_vcDayBufferData, VC_DAY_BUFFER_SIZE);
}


void CE_Update(void)
{
    static int32 i32_firCoef[] = FIR_FILTER_COEF;
    static filter_window t_firWin = { i32_firCoef,
                                      FIR_FILTER_LENGTH,
                                      0 };

    m_f32_voltage = Buffer_Filter( Electrode_GetFirBuffer(ELECTRODE_C), &t_firWin );
    Buffer_Push( &m_t_buffer, m_f32_voltage );
    Buffer_Push(&m_t_vcDayBuffer, m_f32_voltage);

    m_u32_deficitCounter = 0;
    if (m_t_vcDayBuffer.u32_count == m_t_vcDayBuffer.u32_length)
    {
        uint32 i;
        for (i = 0; i < m_t_vcDayBuffer.u32_count; i++)
            if (Buffer_Get(&m_t_vcDayBuffer, i) < 65)
                m_u32_deficitCounter++;
    }

    if ( m_f32_voltage < VOLTAGE_MIN || m_f32_voltage > VOLTAGE_MAX )
    {
        if ( m_u32_railCounter < THRESHOLD_TIME )
            m_u32_railCounter++;
        if ( m_u32_railCounter >= THRESHOLD_TIME )
            m_u32_railCounter = THRESHOLD_TIME * 2 - 1;
    }
    else if (m_u32_railCounter >= THRESHOLD_TIME)
    {
        m_u32_railCounter--;
    }
    else
    {
        m_u32_railCounter = 0;
    }

    if ( m_f32_voltage >= VOLTAGE_SHORTED )
    {
        if ( m_u32_shortedCounter < SHORTED_THRESHOLD_TIME )
            m_u32_shortedCounter++;
    }
    else
    {
        m_u32_shortedCounter = 0;
    }

    if ( m_t_buffer.u32_count == BUFFER_SIZE )
    {
        m_f32_voltageAcc = 0;

        uint8 i = 0;
        for (i=0; i<2; i++)
        {
            fixed32 f32_acc = Buffer_Get( &m_t_buffer, i ) + Buffer_Get( &m_t_buffer, i+2 ) - Buffer_Get( &m_t_buffer, i+1 )*2;
            f32_acc = ABS(f32_acc);
            if (f32_acc > m_f32_voltageAcc)
            {
                m_f32_voltageAcc = f32_acc;
            }
        }
    }
}


fixed32 CE_GetVCounter(void)
{
    return m_f32_voltage;
}


fixed32 CE_GetVCounterRoc(void)
{
    return m_f32_voltage - Buffer_Get( &m_t_buffer, 1 );
}

logical CE_VCounterHigh(void)
{
    return m_f32_voltage > VOLTAGE_REF &&
            Buffer_Get( &m_t_buffer, 1 ) > VOLTAGE_REF &&
            Buffer_Get( &m_t_buffer, 2 ) > VOLTAGE_REF;
}

logical CE_VCounterShorted(void)
{
    return m_u32_shortedCounter >= SHORTED_THRESHOLD_TIME;
}

logical CE_Valid(void)
{
    return m_f32_voltageAcc < VOLTAGE_ACC_MAX;
}


logical CE_Assert(void)
{
    return m_u32_railCounter < THRESHOLD_TIME ;
}

logical CE_Deficit(void)
{
    return m_u32_deficitCounter > VC_DAY_BUFFER_SIZE / 2;
}
